package databases

import (
	"context"
	"fmt"
	"log"

	config "../config"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var mgoCli *mongo.Client

type word_id struct {
	Word    string `json:"word"`
	Tf      int    `json:"tf"`
	Word_id int    `json:"word_id"`
}
type source_docs struct {
	Url   string `json:"url"`
	Title string `json:"title"`
}
type doc_id struct {
	Title             string         `json:"title"`
	Doc_id            int            `json:"doc_id"`
	Seg_title         []string       `json:"seg_title"`
	Seg_title_counter map[string]int `json:"seg_title_counter"`
	Url               string         `json:"url"`
}
type inverted_index struct {
	Word_id       int     `json:"word_id"`
	Inverted_list [][]int `json:"inverted_list"`
	Word_tf       int     `json:"word_tf"`
}

//mongo数据库连接函数
func InitDB() {

	var err error
	//self.motor_uri = "mongodb://{account}{host}:{port}/{database}".format(
	clientOptions := options.Client().ApplyURI(config.BDstring())
	mgoCli, err = mongo.Connect(context.TODO(), clientOptions)
	if err != nil {
		log.Fatal(err)
	}
	err = mgoCli.Ping(context.TODO(), nil)
	if err != nil {
		log.Fatal(err)
	} else {

	}

}

func MongoClient() *mongo.Client {
	if mgoCli == nil {
		InitDB()
	}
	return mgoCli
}

//查询
func find(collection mongo.Collection) {
	InitDB()
	defer mgoCli.Disconnect(context.TODO())
	c := mgoCli.Database("monkey").Collection("Students")
	cur, err := c.Find(context.TODO(), bson.D{{}})
	//bson.D{}里面可写可不写，写了就是条件，不写就是查找全部
	if err != nil {
		log.Fatal(err)
	}
	defer cur.Close(context.TODO())
	for cur.Next(context.TODO()) {
		var result bson.D
		cur.Decode(&result)
		fmt.Println(result.Map())
		fmt.Println(result)
	}
}

//插入
// func mongoinsert() {
// 	initDB()
// 	s1 := Students strut{
// 		Name: "yjy",
// 		Age:  21,
// 	}
// 	//打开数据库并且打开Syudents的这个Collection集合
// 	collection := mgoCli.Database("golang_db").Collection("Students")
// 	one, err := collection.InsertOne(context.TODO(), s1)
// 	if err != nil {
// 		fmt.Println(err)
// 	} else {
// 		fmt.Println(one.InsertedID)
// 	}
// }

//多个插入
// func insertMany() {
// 	initDB()
// 	c := mgoCli.Database("golang_db").Collection("Students")
// 	s1 := Students{
// 		Name: "kitty",
// 		Age:  21,
// 	}
// 	s2 := Students{
// 		Name: "zqy",
// 		Age:  27,
// 	}
// 	stus := []interface{}{s1, s2}
// 	many, err := c.InsertMany(context.TODO(), stus)
// 	if err != nil {
// 		fmt.Println(err)
// 	} else {
// 		fmt.Println(many.InsertedIDs)
// 	}
// }

//更新
func mongoupdate() {
	InitDB()
	c := mgoCli.Database("golang_db").Collection("Students")
	//将数据要改成
	d := bson.D{{"$set", bson.D{{"name", "qxx"}, {"age", "28"}}}}
	//要改的原数据
	many, err := c.UpdateMany(context.TODO(), bson.D{{"name", "kitty"}}, d)
	if err != nil {
		log.Fatal(err)
	}
	//打印改变了多少
	fmt.Println(many.ModifiedCount)
}

//删除
func del() {
	InitDB()
	c := mgoCli.Database("golang_db").Collection("Students")
	many, err := c.DeleteMany(context.TODO(), bson.D{{"name", "qxx"}})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(many.DeletedCount)
}

//这里写go mongo数据库的查询

func MongoCliQuery() []*source_docs {
	var results []*source_docs

	MongoClient := MongoClient()
	collection := MongoClient.Database("monkey").Collection("source_docs")

	cur, err := collection.Find(context.TODO(), bson.D{{"title", "四种免费英汉电子词典软件简评"},
		{"url", "https://www.ruanyifeng.com/blog/2008/02/chinese_english_dictionary_software.html"}})

	if err != nil {

		log.Fatal(err)

	}
	for cur.Next(context.TODO()) {

		//定义一个文档，将单个文档解码为result

		var result source_docs

		err := cur.Decode(&result)

		if err != nil {

			log.Fatal(err)

		}

		results = append(results, &result)

	}

	return results
}

func MongoCliQuery_word_id(query []string) []*word_id {
	var results []*word_id

	MongoClient := MongoClient()
	collection := MongoClient.Database("monkey").Collection("word_id")
	//返回一个游标文件流
	for i := 0; i < len(query); i++ {
		cur, err := collection.Find(context.TODO(), bson.D{{"word", query[i]}})
		if err != nil {

			log.Fatal(err)

		}
		for cur.Next(context.TODO()) {

			//定义一个文档，将单个文档解码为result

			var result word_id

			err := cur.Decode(&result)

			if err != nil {

				log.Fatal(err)

			}
			results = append(results, &result)

		}
	}

	return results
}

func MongoCliQuery_inverted_index(word_id_list []*word_id) []*inverted_index {
	var results []*inverted_index

	MongoClient := MongoClient()
	collection := MongoClient.Database("monkey").Collection("inverted_index")

	for i := 0; i < len(word_id_list); i++ {
		cur, err := collection.Find(context.TODO(), bson.D{{"word_id", word_id_list[i].Word_id}})
		if err != nil {
			log.Fatal(err)
		}
		for cur.Next(context.TODO()) {

			//定义一个文档，将单个文档解码为result

			var result inverted_index
			err := cur.Decode(&result)
			if err != nil {
				log.Fatal(err)
			}
			results = append(results, &result)
		}
	}
	return results
}

func MongoCliQuery_doc_id(doc_id_list []int) []*doc_id {
	var results []*doc_id

	MongoClient := MongoClient()
	collection := MongoClient.Database("monkey").Collection("doc_id")
	for i := 0; i < len(doc_id_list); i++ {
		cur, err := collection.Find(context.TODO(), bson.D{{"doc_id", doc_id_list[i]}})
		if err != nil {
			log.Fatal(err)
		}
		for cur.Next(context.TODO()) {

			//定义一个文档，将单个文档解码为result

			var result doc_id

			err := cur.Decode(&result)

			if err != nil {

				log.Fatal(err)

			}

			results = append(results, &result)

		}

	}
	return results
}
